using System;
using System.Collections.Generic;
using System.Text;

namespace Sedodream.Sudoku.Board
{
	public class CellGroup : ICellGroup
	{
		#region Fields
		private Guid groupId;
		private IBoardData boardData;
		private IList<ICell> cells;
		private int? complexity;
		private IList<int> values;
		private int index;
		private CellGroupType groupType;
		#endregion

		#region Constructors
		public CellGroup(CellGroupType groupType,int index,IBoardData boardData, IList<ICell> cells)
		{
			groupId = Guid.NewGuid();
			this.groupType = groupType;
			this.index = index;
			this.boardData = boardData;
			this.cells = cells;
			//this.BoardData.BoardChanged +=new Sedodream.Sudoku.Events.BoardDataChanged(BoardData_BoardChanged);
		}
		#endregion

		#region ICellGroup implementation
		public Guid GroupId
		{
			get { return this.groupId; }
		}
		public int? Complexity
		{
			get 
			{
				if (!this.complexity.HasValue)
				{
					//update the complexity value here

				}
				return complexity; 
			}
		}
		public IList<ICell> Cells
		{
			get { return cells; }
		}
		public IBoardData BoardData
		{
			get { return boardData; }
		}
		public IList<int> Values
		{
			get 
			{
				//TODO: FIGURE OUT WHY THIS DOESN'T WORK
				//if (values == null)
				{
					values = new List<int>();
					foreach (ICell cell in cells)
					{
						if (cell.CellValue.HasValue)
							values.Add(cell.CellValue.Value);
					}
				}
				return values; 
			}
		}
		public int Index
		{
			get { return index; }
		}
		public ICell this[int index]
		{
			get { return Cells[index]; }
		}
		public CellGroupType GroupType
		{
			get
			{
				return groupType;
			}
		}
		#endregion

		void BoardData_BoardChanged(object sender, Sedodream.Sudoku.Events.BoardChangedEventArgs args)
		{
			this.values = null;
			this.complexity = null;
			//throw new Exception("The method or operation is not implemented.");
		}
		public bool IsPointInGroup(IPoint location)
		{
			if (location == null)
				throw new ArgumentNullException("location");
			foreach (ICell cell in this.Cells)
			{
				if (cell.Location.Equals(location))
					return true;
			}
			return false;
		}
		public override string ToString()
		{
			if (cells == null || cells.Count <= 0)
				return "[]";

			StringBuilder sb = new StringBuilder();
			for(int i =0;i<Cells.Count;i++)
			{
				ICell cell = Cells[i];
				if (i == 0)
					sb.Append("{");

				sb.Append(cell.CellValue != null ? cell.CellValue.Value.ToString() : "0");
				if (i != Cells.Count - 2)
					sb.Append(",");

				if (i == Cells.Count - 1)
					sb.Append("}");
			}

			return sb.ToString();
		}
	}
}
